FIG. 1 (background art) is a block diagram depicting how a modern computerized system can be a complex environment. Generally, one or more software processes are present and employ one or more hardware resources. The software processes can be executing on a single or on multiple processors, and can potentially have multiple threads of execution. For simplicity, each portion of a software process or processes of concern herein is simply termed a “software task.”
In modern a computer operating system (OS) mutex primitives are widely used to protect shared resources from overlapping multi-threaded software access. This is desirable because in most critical-section applications, one or more tasks need to share a resource (e.g., a common data area, a hardware resource, or some other single-access resource). Typically, actual contention for the shared resource is relatively rare, and this mutex protection mechanism is only needed to handle infrequent occasions when more than one task attempts to change a resource at the same time.
Given that the actual resource contention is rare, the processing time required to lock and unlock mutexes is largely wasted effort. The lock and unlock operations often must invoke the kernel of the OS, which can be fairly burdensome in terms of the computing time expended. This is especially the case in a real-time operating system (RTOS). As mutex operations become more burdensome, the critical software sections must be made more coarse-grained, since it becomes less and less economical to lock and unlock the resource in a fine-grained manner due to the overhead this would add.
Furthermore, the management of traditional mutexes by software often requires that processor interrupts be globally disabled while checking and maintaining the states of mutex variables stored in system memory. This is desirably avoided because disabling the interrupts, especially in a RTOS, adds potential latency to the interrupt response.
Another consideration when using software mutexes is priority inversion. A priority inversion occurs when a lower priority task has locked a mutex, and is then blocked for some reason. When a higher priority task then attempts to lock the mutex it is blocked until the lower priority task unlocks the mutex. In the meantime, tasks of intermediate priority may execute, causing the high priority task to wait for an indeterminate amount of time. This is termed “priority inversion” because tasks of intermediate priority are allowed to take precedence over the high priority task indefinitely.
A common solution to the priority inversion problem is to use an OS mutex lock code to temporarily boost the priority of the task which is holding the mutex lock to the same priority as the task which is waiting to acquire the lock. But this adds yet more complexity in implementation and overhead in operation.
Accordingly, what is needed is a mechanism that eliminates or significantly reduces the lock and unlock overhead under non-contending conditions in the kernel of an OS, and that streamlines the response whenever contention does occur. Preferably, such a mechanism should also eliminate the need to disable processor interrupts to check and manage mutexes. And preferably such a mechanism should reduce the burdens of handling priority inversion.